package com.tfswx.ruleengine.fn;

import com.greenpineyu.fel.FelEngine;
import com.greenpineyu.fel.context.ContextChain;
import com.greenpineyu.fel.context.FelContext;
import com.greenpineyu.fel.context.MapContext;
import com.tfswx.ruleengine.compute.bean.*;
import com.tfswx.ruleengine.compute.enums.BdslxEnum;
import com.tfswx.ruleengine.compute.enums.ClqkEnum;
import com.tfswx.ruleengine.compute.gzjy.BaseFn;
import com.tfswx.ruleengine.compute.gzjy.FelService;
import com.tfswx.ruleengine.compute.gzjy.RuleEngineUtil;
import com.tfswx.ruleengine.compute.util.CommonUtil;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;

/**
 * @author Ricky
 * @date 2021/3/25
 */
@Slf4j
public class Calc extends BaseFn {

    @Override
    public Object call(Object[] arguments, FelContext context) {
        FelEngine fel = (FelEngine) context.get("fel");
        String bdsName = String.valueOf(arguments[0]);
        FelContext ctx = new ContextChain(context, new MapContext());

        FelService service = (FelService) context.get("service");
        Bds bds = getBds(bdsName, context);
        BdslxEnum bdslx = bds.getBdslx();
        String bdsStr = bds.getBds().replaceAll("\\s+", " ").trim();
        if (bdslx == BdslxEnum.JS) {
            // 此时表达式形如：getValue($data,'xxxxxxx')=='xx'
            Object eval = fel.eval(bdsStr, ctx);
            GzjyLog.LogDetail logDetail = new GzjyLog.LogDetail();
            logDetail.setBds("calc('" + bds.getBdsmc() + "')");
            logDetail.setBdsbm(bds.getBdsbm());
            logDetail.setBdsmc(bds.getBdsmc());
            logDetail.setBdsms(bds.getBdsms());
            logDetail.setBdsDetail(bdsStr);
            logDetail.setBdslx(bdslx);
            logDetail.setResult(eval);
            service.getGzjyLog().getLogDetailList().add(logDetail);
            return eval;
        } else if (bdslx == BdslxEnum.TS) {
            String wtms = fillBds(bdsStr, fel, ctx);
            List<HczdItem> hczdList = bds.getHczdList();
            List<GzjyjgItem> hcjgxqList = service.getHcjgxqList();
            String zdjybsbh = CommonUtil.getUuid();
            for (HczdItem hczdItem : hczdList) {
                //                FelContext context1 = fel.getContext();
                DataObject dataObject = (DataObject) ctx.get("$data");
                DataObject.ZdItemDTO zd = getZd(dataObject, hczdItem.getZdmc());
                if (zd == null) {
                    continue;
                }
                hcjgxqList.forEach(item -> {
                    if (item.getHczdbh().equals(zd.getHczdbh()) && item.getBdsbm().equals(bds.getBdsbm())) {
                        item.setWtms(wtms);
                        item.setZdjybsbh(zdjybsbh);
                        item.setSffx("Y");
                        item.setClqk(ClqkEnum.WCL);
                    }
                });
            }

            log.info("====>提示：" + wtms);

            GzjyLog.LogDetail logDetail = new GzjyLog.LogDetail();
            logDetail.setBds("calc('" + bds.getBdsmc() + "')");
            logDetail.setBdsbm(bds.getBdsbm());
            logDetail.setBdsmc(bds.getBdsmc());
            logDetail.setBdsms(bds.getBdsms());
            logDetail.setBdsDetail(bdsStr);
            logDetail.setBdslx(bdslx);
            logDetail.setResult(wtms);
            service.getGzjyLog().getLogDetailList().add(logDetail);
            return wtms;
        } else if (bdslx == BdslxEnum.XG) {
            log.info("====>修改");
            Boolean eval = (Boolean) fel.eval(bdsStr, ctx);
            if (Boolean.TRUE.equals(eval)) {
                log.info("修改成功");
            } else {
                log.info("修改失败");
            }
            return null;
        }
        return null;
    }

    String fillBds(String bdsStr, FelEngine fel, FelContext ctx) {
        List<String> fnBdsList = RuleEngineUtil.getFnBdsList(bdsStr);
        String regex;
        for (String fnExp : fnBdsList) {
            Object eval = fel.eval(fnExp, ctx);
            regex = fnExp
                    .replace("\\", "\\\\")
                    .replace("(", "\\(")
                    .replace(")", "\\)")
                    .replace("[", "\\[")
                    .replace("]", "\\]")
                    .replace("{", "\\{")
                    .replace("}", "\\}")
                    .replace(".", "\\.")
                    .replace("$", "\\$")
                    .replace("+", "\\+")
                    .replace("?", "\\?")
                    .replace("^", "\\^");
            bdsStr = bdsStr.replaceFirst(regex, String.valueOf(eval));
        }
        return bdsStr;
    }

    @Override
    public String getZwmc() {
        return "calc";
    }

    @Override
    public List<Param> getParams() {
        List<Param> params = new ArrayList<>();
        params.add(new Param("param1"));
        return params;
    }

    @Override
    public String getName() {
        return "calc";
    }
}
